package org.arch_learn.boot;

import org.arch_learn.boot.annos.FlashBootApplication;
import org.arch_learn.flashboot.context.GlobalContext;
import org.arch_learn.ioc_aop.ioc.BeanFactory;
import org.arch_learn.mvc.auto_config.MvcProperties;
import org.arch_learn.mvc.servlet.GeneralDispatcherServlet;
import org.arch_learn.servlet_container.JerryRat;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import java.io.IOException;
import java.util.Collection;
import java.util.Map;
import java.util.stream.Collectors;

public class FlashBootApplicationStarter {
    private Class<?> applicationStartClass;

    public FlashBootApplicationStarter(Class<?> applicationStartClass) {
        this.applicationStartClass = applicationStartClass;
        GlobalContext.starterPackage = getScanPackage(applicationStartClass);
    }

    public void run() throws IOException {
        //1.初始化全局上下文
        GlobalContext.init();
        //2.启动ioc容器
        BeanFactory.start();
        //3.mvc自动装配/加载servlets
        Map<String, HttpServlet> servlets = loadServlets();
        loadOnStartUpIfNecessary(servlets.values());
        //4.启动servlet容器
        JerryRat webServer = GlobalContext.getInstance(JerryRat.class);
        webServer.addServlets(servlets);
        webServer.run();
    }

    private void loadOnStartUpIfNecessary(Collection<HttpServlet> servlets) {
        MvcProperties mvcProperties = GlobalContext.getInstance(MvcProperties.class);
        if (mvcProperties.getLoadOnStartUp() == 1) {
            servlets.forEach(servlet -> {
                try {
                    servlet.init();
                } catch (ServletException e) {
                    e.printStackTrace();
                }
            });
        }
    }

    private String getScanPackage(Class<?> clazz) {
        FlashBootApplication flashBootApplicationStarterAnno = clazz.getAnnotation(FlashBootApplication.class);
        String scanPackage = flashBootApplicationStarterAnno.scanPackage();
        if ("".equals(scanPackage)) {
            scanPackage = clazz.getPackage().getName();
        }
        return scanPackage;
    }

    private Map<String, HttpServlet> loadServlets() {
        return GlobalContext.getInstances(GeneralDispatcherServlet.class)
                .stream()
                .collect(Collectors.toMap(v -> v.getServletContextPath(), v -> v));
    }
}
